package com.example.core;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * bean 工厂, 通过spring容器获取容器中定义的bean
 * 
 * @author  rch
 * @date	2020-07-18
 */
@Configuration
public class BeanFactory implements ApplicationContextAware
{
    /**
     * Spring应用上下文环境
     */
    private static ApplicationContext context;
  
    /** 
     * 实现ApplicationContextAware接口的回调方法，设置上下文环境 
     *  
     * @param applicationContext 
     */  
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
    {  
        context = applicationContext;  
    }
    
    /** 
     * @return ApplicationContext 
     */  
    final public static ApplicationContext getApplicationContext()
    {
        return context;  
    }  
  
    public static Object getBean(String name)
    {
        return context.getBean(name);
    }

    public static <T> T getBean(String name, Class<T> requiredType)
    {
        return context.getBean(name, requiredType);
    }
    
    public static <T> T getBean(Class<T> requiredType)
    {
        return context.getBean(requiredType);
    }
  
    public static Object getBean(String name, Object... args)
    {
        return context.getBean(name, args);
    }
    
    public static <T> Map<String, T> getBeansOfType(Class<T> type)
    {
        return context.getBeansOfType(type);
    }
    
    public static <T> List<T> getBeans(Class<T> type)
    {
        Collection<T> beans = context.getBeansOfType(type).values();

//        @SuppressWarnings("unchecked")
//        T[] a =  (T[])Array.newInstance(type.getClass(), beans.size());
//        List<T> result = (List<T>)Arrays.asList(beans.toArray(a));
        
        @SuppressWarnings("unchecked")
        List<T> result = (List<T>)Arrays.asList(beans.toArray());
        
        return result;
    }

    public static boolean containsBean(String name)
    {
        return context.containsBean(name);
    }

    final public static ApplicationContext loadContext()
    {  
        context = new ClassPathXmlApplicationContext("spring_mysql.xml");

        return context;  
    }  

    public static void main(String[] args)
    {
//        Map<String, LoginPlugin> plugins = getBeansOfType(LoginPlugin.class);
//        
//        for (Map.Entry<String, LoginPlugin> element: plugins.entrySet())
//        {
//            System.out.println(element.getKey() + ": " + element.getValue());
//        }
    }
}

